import 'package:core_foundation/utils/utils_dialog.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:fluttertoast/fluttertoast.dart';

import 'interceptors/log_interceptor.dart';
import 'interceptors/network_interceptor.dart';
import 'code.dart';
import 'interceptors/response_interceptor.dart';
import 'result_data.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:cookie_jar/cookie_jar.dart';


///
///
class HttpManager {
  Dio _dio = Dio(); //初始一个默认的配置
  var cookieJar = CookieJar();
  HttpManager() {
    _dio.interceptors.add(CookieManager(cookieJar));
    _dio.interceptors.add(InterceptorNetwork(_dio));
    _dio.interceptors.add(InterceptorLog());
    _dio.interceptors.add(InterceptorResponse());
  }

  Dio getDio() => _dio;

  Future<ResultData> get(String url, {Map<String, dynamic> params, Map<String, dynamic> header, BuildContext context}) async {
    Options options = Options(method: "get");
    return await query(url, options, params: params, context: context);
  }

  Future<ResultData> post(String url, { params, Map<String, dynamic> header, BuildContext context}) async {
    Options options = Options(method: "post");
    if (null != header && header.isNotEmpty) {
      options.headers.addAll(header);
    }else {
      header = {
        "Accept":"application/json",
        "Content-Type":"application/json; charset=UTF-8",
      };
      options.headers.addAll(header);
    }
    return await request(url, options, params: params, context: context);
  }
  ///请求和返回统一错误处理
  handleDioError(DioError err, {BuildContext context}) {
    ResultData resultData ;

    if (null != err) {
      switch(err.type) {
        case DioErrorType.DEFAULT:
          String errMsg = "";
          if (err.message != null) {
            errMsg = err.message;
          }
          if (errMsg.contains("Connection timed out")) {
            Fluttertoast.showToast(msg: "连接超时,请确保当前网络能正常访问服务!");
            resultData = ResultData(Code.NETWORK_TIMEOUT, errMsg);
          } else if(err.error is ResultData) {
            Fluttertoast.showToast(msg: "没有网络，请检查您的网络");
            resultData = err.error;
          } else {
            resultData = ResultData(Code.NETWORK_ERROR, err.message);
          }
          break;
        case DioErrorType.CONNECT_TIMEOUT:
        case DioErrorType.RECEIVE_TIMEOUT:
        case DioErrorType.SEND_TIMEOUT:
          Fluttertoast.showToast(msg: "网络链接超时,请检查您的网络!");
          resultData = ResultData(Code.NETWORK_TIMEOUT, "");
          break;
        case DioErrorType.RESPONSE:
          int statusCode = err.response.statusCode;

          if (statusCode >= 400 && statusCode <500) {
            resultData = ResultData(Code.FAILURE, err.response.data);
          }else if (statusCode >= 500) {
            Fluttertoast.showToast(msg: "服务器异常,请稍后再试!");
            resultData = ResultData(Code.SERVER_ERROR, err.response.data);
          }
          break;

      }
    }
    return resultData;
  }

  /// post统一请求体
  Future<ResultData> request(String url, Options options, {params, BuildContext context}) async {
    Response response;
    if (null != context) UtilsDialog.showLoadingDialog(context);

    try {
      response = await _dio.request(url, data: params, options: options);
    }on DioError catch(e) {
      return handleDioError(e, context: context);
    } finally{
      if (null != context) {
        Navigator.pop(context);
        context = null;
      }
    }
    if (response.data is DioError) {
      return handleDioError(response.data, context: context);
    }


    return response.data;
  }

  ///get post统一请求体
  Future<ResultData> query(String url, Options options, {Map<String, dynamic> params, BuildContext context}) async {
    Response response;
    if (null != context) UtilsDialog.showLoadingDialog(context);

    try {
      response = await _dio.request(url, queryParameters: params, options: options);
    }on DioError catch(e) {
      return handleDioError(e, context: context);
    } finally{
      if (null != context) {
        Navigator.pop(context);
        context = null;
      }
    }
    if (response.data is DioError) {
      return handleDioError(response.data, context: context);
    }

    return response.data;
  }


  /// 表单上传文件,
  Future<ResultData> uploadSingleFile(String url, Options options, {Map<String, dynamic> formData, String filePath, BuildContext context, ProgressCallback onSendProgress}) async {
    Response response;
    try {
      if (null != formData){
        formData["file"] = await MultipartFile.fromFile(filePath);
        }
      response = await _dio.post(url, data: formData, options: options, onSendProgress: onSendProgress);
    }on DioError catch(e) {
      return handleDioError(e, context: context);
    }
    if (response.data is DioError) {
      return handleDioError(response.data, context: context);
    }

    return response.data;
  }



}

final HttpManager httpManager = HttpManager();
